//在构造函数中可以使用this来引用新建的对象
// 使用工厂模式创建对象
function createPerson(name, age) {
    // 创建新的对象
    const obj = new Object();
    // 设置对象属性
    obj.name = name;
    obj.age = age;
    // 设置对象方法
    obj.sayName = function () {
        console.log(this.name);
    };
    //返回新的对象
    return obj;
}

for (let i = 1; i <= 3; i++) {
    const person = createPerson("person" + i, 18);
    console.log(typeof person);
}


console.log("______________________________________________")
//创建一个全局变量name
//const name = "全局变量name";显示name未使用过

//创建一个函数
function fun() {
    console.log(this.name);
}

//创建一个对象
const obj = {
    name: "孙悟空",
    sayName: fun
};

//我们希望调用obj.sayName()时可以输出obj的名字而不是全局变量name的名字
obj.sayName();

console.log("______________________________________________")
// 使用构造函数来创建对象
function Person(name, age) {
    // 设置对象的属性
    this.name = name;
    this.age = age;
    // 设置对象的方法
    this.sayName = sayName
}

// 抽取方法为全局函数
function sayName() {
    console.log(this.name);
}

const person1 = new Person("孙悟空", 18);
const person2 = new Person("猪八戒", 19);
const person3 = new Person("沙和尚", 20);

person1.sayName();
person2.sayName();
person3.sayName();
console.log("______________________________________________")
//可以使用 instanceof 运算符检查一个对象是否是一个类的实例，它返回true或false
// 使用构造函数来创建对象
function Person1(name, age) {
    // 设置对象的属性
    this.name = name;
    this.age = age;
}

//创建对象的一个实例对象
const p = new Person1("张三", 20);
console.log(p.toString());
console.log("______________________________________________")
// 创造一个构造函数
function MyClass() {
}

// 向MyClass的原型中添加一个name属性
MyClass.prototype.name = "我是原型中的名字";

// 创建一个MyClass的实例
var mc = new MyClass();
mc.age = 18;

// 使用in检查对象中是否含有某个属性时，如果对象中没有但是原型中有，也会返回true
console.log("age" in mc);
console.log("name" in mc);

// 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性，使用该方法只有当对象自身中含有属性时，才会返回true
console.log(mc.hasOwnProperty("age"));
console.log(mc.hasOwnProperty("name"));
console.log("______________________________________________")
// 定义父类型构造函数
function SupperType() {
    this.supProp = 'Supper property';
}

// 给父类型的原型添加方法
SupperType.prototype.showSupperProp = function () {
    console.log(this.supProp);
};

// 定义子类型的构造函数
function SubType() {
    this.subProp = 'Sub property';
}

// 创建父类型的对象赋值给子类型的原型
SubType.prototype = new SupperType();

// 将子类型原型的构造属性设置为子类型
SubType.prototype.constructor = SubType;

// 给子类型原型添加方法
SubType.prototype.showSubProp = function () {
    console.log(this.subProp)
};

// 创建子类型的对象: 可以调用父类型的方法
var subType = new SubType();
subType.showSupperProp();
subType.showSubProp();
console.log("______________________________________________")
function Person2(name, age) {
    this.name = name;
    this.age = age;
}

Person2.prototype.setName = function (name) {
    this.name = name;
};

function Student(name, age, price) {
    Person2.call(this, name, age); // 为了得到父类型的实例属性和方法
    this.price = price; // 添加子类型私有的属性
}

Student.prototype = new Person2(); // 为了得到父类型的原型属性和方法
Student.prototype.constructor = Student; // 修正constructor属性指向
Student.prototype.setPrice = function (price) { // 添加子类型私有的方法
    this.price = price;
};

const s = new Student("孙悟空", 24, 15000);
console.log(s.name, s.age, s.price);
s.setName("猪八戒");
s.setPrice(16000);
console.log(s.name, s.age, s.price);
console.log("______________________________________________")







